package cn.hackcloud.mutithread.juc;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

import org.junit.Test;

/**
 * 分支合并框架
 * 
 * @author Created by laijun on 2018/12/11
 */
public class TestForkJoinTask {
	public static void main(String[] args) throws Exception {
		Instant start = Instant.now();
		ForkJoinPool forkJoinPool = new ForkJoinPool();
		ForkJoinSumCaculate caculate = new ForkJoinSumCaculate(0L, 50000000000L);
		Long task = forkJoinPool.invoke(caculate);
		System.out.println(task);
		Instant end = Instant.now();
		System.out.println("耗费时间:" + Duration.between(start, end).toMillis() + "毫秒");
	}

	@Test
	public void testSum() {
		Instant start = Instant.now();
		long sum = 0l;
		for (long i = 0; i <= 50000000000L; i++) {
			sum += i;
		}
		System.out.println(sum);
		Instant end = Instant.now();
		System.out.println("耗费时间:" + Duration.between(start, end).toMillis() + "毫秒");
	}
}

class ForkJoinSumCaculate extends RecursiveTask<Long> {
	private static final long serialVersionUID = 1L;
	private Long start;
	private Long end;
	private static final Long THURSHOLD = 10000L;// 临界值

	public ForkJoinSumCaculate(long start, long end) {
		this.start = start;
		this.end = end;
	}

	@Override
	protected Long compute() {
		Long length = end - start;
		if (length <= THURSHOLD) {
			long sum = 0l;
			for (Long i = start; i <= end; i++) {
				sum += i;
			}
			return sum;
		} else {
			long middel = (start + end) / 2;
			ForkJoinSumCaculate left = new ForkJoinSumCaculate(start, middel);
			left.fork();
			ForkJoinSumCaculate right = new ForkJoinSumCaculate(middel + 1, end);
			right.fork();
			return left.join() + right.join();
		}
	}

}
